package com.liuzy.dsoframer.controller;

import com.liuzy.dsoframer.util.DiskFile;
import com.liuzy.dsoframer.util.DiskFileUtil;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.PageOfficeCtrl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

@Slf4j
@Controller
@RequestMapping("/")
public class IndexController {
    @Value("${srvDir}")
    private String srvDir;
    @Value("${winDir}")
    private String winDir;
    @Value("${macDir}")
    private String macDir;

    private File dir;

    @PostConstruct
    public void init() {
        String name = System.getProperty("os.name").toLowerCase();
        if (name.contains("windows")) {
            dir = new File(winDir);
        } else if (name.contains("linux")) {
            dir = new File(srvDir);
        } else {
            dir = new File(macDir);
        }
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    @RequestMapping("/")
    public String index(
            Model model
    ) {
        List<DiskFile> list = DiskFileUtil.list(dir);
        list.sort(Comparator.comparing(DiskFile::getName));
        model.addAttribute("data", list);
        return "index";
    }

    @GetMapping("/download/{id}")
    public void download(
            @PathVariable String id,
            HttpServletResponse resp
    ) {
        File file = DiskFileUtil.find(dir, id);
        if (file == null || !file.exists()) {
            resp.setStatus(404);
            return;
        }
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
             OutputStream os = resp.getOutputStream()) {
            resp.addHeader("Content-Disposition", "attachment; fileName=" + file.getName());
            byte[] buffer = new byte[1024];
            int i;
            while ((i = bis.read(buffer)) != -1) {
                os.write(buffer, 0, i);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    @PostMapping("/upload")
    @ResponseBody
    public String upload(
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "file") MultipartFile multipartFile
    ) {
        return DiskFileUtil.save(dir, id, multipartFile);
    }

    @PostMapping("/uploadAndSend")
    @ResponseBody
    public String uploadAndSend(
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "file") MultipartFile multipartFile
    ) {
        return DiskFileUtil.save(dir, id, multipartFile);
    }

    @PostMapping("/send")
    @ResponseBody
    public String send(
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "to", required = false) String to
    ) {
        log.info("id=" + id + " to=" + to);
        return "Send OK";
    }

    @GetMapping("/delete/{id}")
    public String delete(
            @PathVariable(value = "id") String id
    ) {
        DiskFileUtil.delete(dir, id);
        return "redirect:/";
    }

    @GetMapping("/versions/{id}")
    @ResponseBody
    public List<DiskFile> versions(
            @PathVariable(value = "id", required = false) String id
    ) {
        List<DiskFile> list = DiskFileUtil.list(dir);
        DiskFile current = list.stream().filter(f -> f.getMd5().equals(id)).findFirst().orElse(null);
        List<DiskFile> versions = new ArrayList<>();
        if (current != null) {
            String prefix = current.getName().substring(0, current.getName().lastIndexOf("."));
            while (true) {
                if (prefix.length() > 14 && Pattern.matches("^\\_[\\d]{14}$", prefix.substring(prefix.length() - 15))) {
                    prefix = prefix.substring(0, prefix.length() - 15);
                } else {
                    break;
                }
            }
            for (DiskFile f : list) {
                if (f.getName().startsWith(prefix)) {
                    versions.add(f);
                }
            }
            versions.sort(Comparator.comparing(DiskFile::getName));
        }
        return versions;
    }

    @GetMapping("/compare")
    public String compare(
            HttpServletRequest request,
            @RequestParam(value = "fileA", required = false) String fileA,
            @RequestParam(value = "fileB", required = false) String fileB,
            @RequestParam(value = "username", required = false) String username,
            Model model
    ) {
        PageOfficeCtrl poCtrl1 = new PageOfficeCtrl(request);
        poCtrl1.setServerPage("/zz/poserver.zz");

        // Create custom toolbar
        poCtrl1.addCustomToolButton("显示A文档", "ShowFile1View()", 0);
        poCtrl1.addCustomToolButton("显示B文档", "ShowFile2View()", 0);
        poCtrl1.addCustomToolButton("显示比较结果", "ShowCompareView()", 0);

        //poCtrl1.wordCompare("doc/aaa1.doc", "doc/aaa2.doc", OpenModeType.docReadOnly, "张三");
        poCtrl1.wordCompare("/download/" + fileA, "/download/" + fileB, OpenModeType.docAdmin, username);

        model.addAttribute("htmlCode", poCtrl1.getHtmlCode("PageOfficeCtrl1"));
        return "compare";
    }
}
